#ifndef __MSG_QUEUE_MGR_H__
#define __MSG_QUEUE_MGR_H__

#include "utils/singleton.h"
#include "./msgqueue.h"

#define MSG_QUEUE_SIZE 1000

#define PUSH_MSG_QUEUE(TMsg, queueIndex, msg)\
	MsgQueueMgr::GetInstance().PushQueue<TMsg>(queueIndex, msg);

#define POP_MSG_QUEUE(TMsg, queueIndex)\
	MsgQueueMgr::GetInstance().PopQueue<TMsg>(queueIndex);

#define POPCLEAR_MSG_QUEUE(TMsg, queueIndex)\
	MsgQueueMgr::GetInstance().PopAndClearQueue<TMsg>(queueIndex);

class MsgQueueMgr : public Singleton<MsgQueueMgr>
{
public:
	MsgQueueMgr();
	~MsgQueueMgr();

	template <class TMsg>
	inline size_t RegisterQueue()
	{
		MsgQueue<TMsg>* queue = new MsgQueue<TMsg>(MSG_QUEUE_SIZE);
		m_queuelist.push_back(reinterpret_cast<void*>(queue));
		return m_queuelist.size() - 1;
	}

	template <class TMsg>
	inline void UnRegisterQueue(size_t queueIndex)
	{
		delete m_queuelist[queueIndex];
		m_queuelist[queueIndex] = NULL;

		bool canDestroy = true;

		vector<void*>::iterator iter;
		for (iter = m_queuelist.begin(); iter != m_queuelist.end(); ++iter)
		{
			if (*iter)
			{
				canDestroy = false;
			}
		}
		
		if (canDestroy)
		{
			m_queuelist.clear();
		}
	}

	template <class TMsg>
	inline void PushQueue(size_t queueIndex, TMsg& msg)
	{
		MsgQueue<TMsg>* queue = reinterpret_cast<MsgQueue<TMsg>*>(m_queuelist[queueIndex]);
		if (queue)
		{
			queue->Push(msg);
		}
	}

	template <class TMsg>
	inline TMsg* PopQueue(size_t queueIndex)
	{
		MsgQueue<TMsg>* queue = reinterpret_cast<MsgQueue<TMsg>*>(m_queuelist[queueIndex]);
		return queue->Pop();
	}

	template <class TMsg>
	inline TMsg* PopAndClearQueue(size_t queueIndex)
	{
		MsgQueue<TMsg>* queue = reinterpret_cast<MsgQueue<TMsg>*>(m_queuelist[queueIndex]);
		return queue->PopAndClear();
	}

private:
	vector<void*> m_queuelist;
};

#endif